# -*- coding: utf-8 -*-

import re
import threading
import time
from queue import Queue # 队列模块

import requests
from lxml import etree


# 生产者: 生产数据(获取图片链接， 图片标题)
class Producer(threading.Thread):

    # 初始化方法
    def __init__(self, page_queue, img_queue):
        # 在子类同时执行 父类的方法
        super().__init__()  # 去调用父类的init方法
        self.page_queue = page_queue # 存放url的队列
        self.img_queue = img_queue # 存放数据的队列


    def run(self):
        while True:
            # 如果为空: 返回的True
            if self.page_queue.empty():
                break
            url = self.page_queue.get()
            # print(url)  # 获取url，发请求，解析数据
            self.get_img(url)  # 方法就是属于run方法里面的一部分

    # 获取图片链接
    def get_img(self, url):
        # 发请求，获取响应
        res = requests.get(url)
        # 打印响应内容
        # print(res.text)
        # 解析数据
        html = etree.HTML(res.text)
        # 采用xpath解析数据  获取所有的img标签
        imag = html.xpath('//img[@class="ui image lazy"]')
        # print(len(imag))  # 确定所有的元素 已经拿到了
        for img in imag:
            # 获取图片的标题以及图片url
            img_title = img.xpath('@alt')[0]
            img_title = re.sub(r'[*/\\ :.?]', '', img_title)
            img_url = img.xpath('@data-original')[0]
            # 提取图片的后缀名
            hzm = img_url.split('.')[-1]  # 生产者生产出数据， 队列
            # 将数据存放到队列当中  列表  字典  元组
            self.img_queue.put((img_title, img_url, hzm))
            print(self.img_queue.qsize())  # 查看队列的大小

# 消费者: 消费处理数据(保存图片)
class Consumer(threading.Thread):

    # 初始化方法
    def __init__(self, img_queue):
        # 在子类同时执行 父类的方法
        super().__init__()  # 去调用父类的init方法
        self.img_queue = img_queue  # 存放数据的队列

    def run(self):
        while True:
            # 判断数据队列是否为空 ， 为空， 终止循环
            if self.img_queue.empty():
            #     print(111)
                break
            img_data = self.img_queue.get() # 元组
            img_title, img_url, hzm = img_data  # 元组里面的数据依次赋值
            head = {
                'referer': 'https://fabiaoqing.com/biaoqing'
            }
            # 向图片链接发请求，得到响应
            res1 = requests.get(img_url, headers=head)
            # 保存图片  动态图: gif  静态图: jpg,png
            with open(f'images/{img_title}.{hzm}', 'wb') as f:
                f.write(res1.content)
            print(f'{img_title}下载成功')

if __name__ == '__main__':
    start = time.time()
    # 存放队列的url
    page_queue = Queue()
    # 存放数据的队列
    img_queue = Queue()
    for page in range(1,3):
        url = f'https://fabiaoqing.com/biaoqing/lists/page/{page}.html'
        page_queue.put(url)

    lst = []
    # 创建三个生产者
    for i in range(3):
        # 实例化对象，默认会调用初始化方法(init)
        t = Producer(page_queue, img_queue)  # 将存放url的队列传给生产者
        # 开启线程
        t.start()
        lst.append(t)

    for t in lst:   # 生产者生产完了数据才执行的消费者
        t.join()


    # 创建三个消费者
    lst1 = []
    for j in range(3):
        # 实例化对象
        t = Consumer(img_queue)
        t.start()
        lst1.append(t)

    for t1 in lst1:
        t1.join()

    end = time.time()
    print(f'程序运行所花费的时间{end-start}')

# 程序运行所花费的时间12.983084201812744
